package com.dbumama.market.web.core.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.log.Log;

import javax.net.ssl.SSLException;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;

/**
 * 联网鉴查测试
 */
public class FacePlusPlus {
	
	public static void main(String[] args) {
		getBankCardInfo("C:/Users/doyo/Desktop/new/BankCard测试.jpg");
	}
	
	private Log log= Log.getLog(FacePlusPlus.class);
	
	public static final String api_key = "9iuucIOr77CO9DJ-akZr4Brjw180wbAg";

	public static final String api_secret = "f3nBNA4wTTN7_IY9owOWJp5Ln2YfRRgK";
	
	public static final String HTTPSURL = "https://api-cn.faceplusplus.com/cardpp/"; 
	
	private final static int CONNECT_TIME_OUT = 30000;
    private final static int READ_OUT_TIME = 50000;
    private static String boundaryString = getBoundary();

	/*请求参数
	 * 必选
	api_key
	String
	调用此API的API Key
	必选
	api_secret
	String
	调用此API的API Secret
	必选（三选一）
	 
	image_url
	String
	图片的URL
	注：在下载图片时可能由于网络等原因导致下载图片时间过长，建议使用 image_file 或image_base64 参数直接上传图片。
	image_file
	File
	一个图片，二进制文件，需要用 post multipart/form-data 的方式上传。
	image_base64	String	
	base64编码的二进制图片数据
	如果同时传入了image_url、image_file和image_base64参数，本API使用顺序为image_file优先，image_url最低。
	可选
	legality
	Int
	是否返回身份证照片合法性检查结果。值可以取：
	1: 返回
	0: 不返回
	注：默认值为 0
	注意：2017年6月7日之后，只有正式 API Key 能够调用此参数返回分类结果，免费 API Key 调用后无法返回分类结果。*/
    
	public static JSONObject getIdCardInfo(String imgUrl){
		JSONObject resultJson = new JSONObject();
		byte[] buff = ImageCompress.ImageScale(imgUrl, 1000, 1000);
		HashMap<String, String> map = new HashMap<>();
	    HashMap<String, byte[]> byteMap = new HashMap<>();
	    map.put("api_key",api_key);
	    map.put("api_secret",api_secret);
	    byteMap.put("image_file", buff);
	    byte[] retJson;
		try {
			retJson = post(HTTPSURL + "v1/ocridcard",map, byteMap);
			JSONObject retObj = JSONObject.parseObject(new String(retJson,"utf-8"));
			JSONArray cards= JSON.parseArray(retObj.getString("cards"));
			
			Iterator<Object> cardsIt = cards.iterator();
	        while (cardsIt.hasNext()) {
	        	
	        	JSONObject card = (JSONObject) cardsIt.next();
	        	
	        	String name = card.getString("name");
	        	String cardNumber = card.getString("id_card_number");
	        	String issued_by = card.getString("issued_by");
	        	String valid_date = card.getString("valid_date");
	        	resultJson.put("name",name );
				resultJson.put("id_card_number",cardNumber );
				resultJson.put("issued_by",issued_by );// 公安局发行地址
				resultJson.put("valid_date",valid_date );// 有效期
	        }
	        
			System.out.println("cards="+cards);
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("resultJson="+resultJson);
		return resultJson;
	}
	

	public static JSONObject getBankCardInfo(String imgUrl){
		JSONObject resultJson = new JSONObject();
		byte[] buff = ImageCompress.ImageScale(imgUrl, 1000, 1000);
		HashMap<String, String> map = new HashMap<>();
	    HashMap<String, byte[]> byteMap = new HashMap<>();
	    map.put("api_key",api_key);
	    map.put("api_secret",api_secret);
	    byteMap.put("image_file", buff);
	   /* byte[] retJson;
		try {
			retJson = post(HTTPSURL + "beta/ocrbankcard",map, byteMap);
			Map<String,Object> resultMap = JSONObject.parseObject(retJson, Map.class);
			List bank_cards = (List) resultMap.get("bank_cards");
			System.out.println(resultMap);
			System.out.println(bank_cards);
			resultJson.put("cardno", );
			resultJson.put("bankname", );
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return resultJson;*/
	    byte[] retJson;
		try {
			retJson = post(HTTPSURL + "beta/ocrbankcard",map, byteMap);
			JSONObject retObj = JSONObject.parseObject(new String(retJson,"utf-8"));
			JSONArray cards= JSON.parseArray(retObj.getString("bank_cards"));
			
			Iterator<Object> cardsIt = cards.iterator();
	        while (cardsIt.hasNext()) {
	        	
	        	JSONObject card = (JSONObject) cardsIt.next();
	        	
	        	String number = card.getString("number");
	        	resultJson.put("cardno",number );
				resultJson.put("bankname","");
	        }
	        
			System.out.println("bank_cards="+cards);
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("resultJson="+resultJson);
		return resultJson;
		
	}
	

    protected static byte[] post(String url, HashMap<String, String> map, HashMap<String, byte[]> fileMap) throws Exception {
        HttpURLConnection conne;
        URL url1 = new URL(url);
        conne = (HttpURLConnection) url1.openConnection();
        conne.setDoOutput(true);
        conne.setUseCaches(false);
        conne.setRequestMethod("POST");
        conne.setConnectTimeout(CONNECT_TIME_OUT);
        conne.setReadTimeout(READ_OUT_TIME);
        conne.setRequestProperty("accept", "*/*");
        conne.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
        conne.setRequestProperty("connection", "Keep-Alive");
        conne.setRequestProperty("user-agent", "Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1)");
        DataOutputStream obos = new DataOutputStream(conne.getOutputStream());
        Iterator iter = map.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry<String, String> entry = (Map.Entry) iter.next();
            String key = entry.getKey();
            String value = entry.getValue();
            obos.writeBytes("--" + boundaryString + "\r\n");
            obos.writeBytes("Content-Disposition: form-data; name=\"" + key
                    + "\"\r\n");
            obos.writeBytes("\r\n");
            obos.writeBytes(value + "\r\n");
        }
        if(fileMap != null && fileMap.size() > 0){
            Iterator fileIter = fileMap.entrySet().iterator();
            while(fileIter.hasNext()){
                Map.Entry<String, byte[]> fileEntry = (Map.Entry<String, byte[]>) fileIter.next();
                obos.writeBytes("--" + boundaryString + "\r\n");
                obos.writeBytes("Content-Disposition: form-data; name=\"" + fileEntry.getKey()
                        + "\"; filename=\"" + encode(" ") + "\"\r\n");
                obos.writeBytes("\r\n");
                obos.write(fileEntry.getValue());
                obos.writeBytes("\r\n");
            }
        }
        obos.writeBytes("--" + boundaryString + "--" + "\r\n");
        obos.writeBytes("\r\n");
        obos.flush();
        obos.close();
        InputStream ins = null;
        int code = conne.getResponseCode();
        try{
            if(code == 200){
                ins = conne.getInputStream();
            }else{
                ins = conne.getErrorStream();
            }
        }catch (SSLException e){
            e.printStackTrace();
            return new byte[0];
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buff = new byte[4096];
        int len;
        while((len = ins.read(buff)) != -1){
            baos.write(buff, 0, len);
        }
        byte[] bytes = baos.toByteArray();
        ins.close();
        return bytes;
    }
    private static String getBoundary() {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for(int i = 0; i < 32; ++i) {
            sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".charAt(random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".length())));
        }
        return sb.toString();
    }
    private static String encode(String value) throws Exception{
        return URLEncoder.encode(value, "UTF-8");
    }
    
    public static byte[] getBytesFromFile(File f) {
        if (f == null) {
            return null;
        }
        try {
            FileInputStream stream = new FileInputStream(f);
            ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = stream.read(b)) != -1)
                out.write(b, 0, n);
            stream.close();
            out.close();
            return out.toByteArray();
        } catch (IOException e) {
        }
        return null;
    }
}
